<?php
/*
* Twitter Datasource
* Version 0.1
* Created: 7/6/2010
* Creator: http://twitter.com/yoophi
*	
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*/
App::import('Core',array('Xml','HttpSocket'));
class TwitterSource extends DataSource {
	public $description = 'Twitter API with HTTP_Basic_Auth';
	public $httpSocket = null;

    public $base_api_url = 'http://twitter.com/';
    public $base_search_url = 'http://search.twitter.com/';
    // public $base_api_url = 'http://192.168.0.97/statusnet/api/';
    // public $base_search_url = 'http://search.twitter.com/';

	/* Public Methods */
	function __construct($config) {
		parent::__construct($config);
		$this->httpSocket =& new HttpSocket();
		$this->config = $config;
	}

    function setAPIUrl($base_api_url, $base_search_url) {
        foreach(array('base_api_url', 'base_search_url') as $key) {
            if (substr($$key, -1) !== '/') {
                $$key = $$key . '/';
            }
            $this->{$key} = $$key;
        }
    }
	/* Twitter API Wrappers */
    /* Search API */
	function search($params=array()) {
		$url = $this->base_search_url . 'search.json';
		return $this->__query($url,$params,'get');
	}
	function trends($params=array()) {
		$url = $this->base_search_url . 'trends.json';
		return $this->__query($url,$params,'get');
	}
	function trends_current($params=array()) {
		$url = $this->base_search_url . 'trends/current.json';
		return $this->__query($url,$params,'get');
	}
	function trends_daily($params=array()) {
		$url = $this->base_search_url . 'trends/daily.json';
		return $this->__query($url,$params,'get');
	}
	function trends_weekly($params=array()) {
		$url = $this->base_search_url . 'trends/weekly.json';
		return $this->__query($url,$params,'get');
	}
    /* REST API */
    /* Timeline Wrappers */
	function statuses_public_timeline($params=array()) {
		$url = $this->base_api_url . 'statuses/public_timeline.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_home_timeline($params=array()) {
		$url = $this->base_api_url . 'statuses/home_timeline.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_friends_timeline($params=array()) {
		$url = $this->base_api_url . 'statuses/friends_timeline.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_user_timeline($params=array()) {
		$url = $this->base_api_url . 'statuses/user_timeline.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_mentions($params=array()) {
		$url = $this->base_api_url . 'statuses/mentions.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_retweeted_by_me($params=array()) {
		$url = $this->base_api_url . 'statuses/retweeted_by_me.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_retweeted_to_me($params=array()) {
		$url = $this->base_api_url . 'statuses/retweeted_to_me.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_retweeted_of_me($params=array()) {
		$url = $this->base_api_url . 'statuses/retweeted_of_me.json';
		return $this->__query($url,$params,'get');
	}
    /* Status Wrappers */
	function statuses_show($params=array()) {
		$url = $this->base_api_url . 'statuses/show.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_update($params=array()) {
		$url = $this->base_api_url . 'statuses/update.json';
		return $this->__query($url,$params,'post');
	}
	function statuses_destroy($params=array()) {
		$url = $this->base_api_url . 'statuses/destroy.json';
		return $this->__query($url,$params,'post');
	}
	function statuses_retweet($params=array()) {
		$url = $this->base_api_url . 'statuses/retweet.json';
		return $this->__query($url,$params,'post');
	}
	function statuses_retweets($params=array()) {
		$url = $this->base_api_url . 'statuses/retweets.json';
		return $this->__query($url,$params,'get');
	}
    /* User */
	function users_show($params=array()) {
		$url = $this->base_api_url . 'users/show.json';
		return $this->__query($url,$params,'get');
	}
	function users_search($params=array()) {
		$url = $this->base_api_url . 'users/search.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_friends($params=array()) {
		$url = $this->base_api_url . 'statuses/friends.json';
		return $this->__query($url,$params,'get');
	}
	function statuses_followers($params=array()) {
		$url = $this->base_api_url . 'statuses/followers.json';
		return $this->__query($url,$params,'get');
	}
    /* Direct Message */
	function direct_messages($params=array()) {
		$url = $this->base_api_url . 'direct_messages.json';
		return $this->__query($url,$params,'get');
	}
	function direct_messages_sent($params=array()) {
		$url = $this->base_api_url . 'direct_messages/sent.json';
		return $this->__query($url,$params,'get');
	}
	function direct_messages_new($params=array()) {
		$url = $this->base_api_url . 'direct_messages/new.json';
		return $this->__query($url,$params,'post');
	}
	function direct_messages_destroy($params=array()) {
		$url = $this->base_api_url . 'direct_messages/destroy.json';
		return $this->__query($url,$params,'post');
	}
			/* Friendship */
	function friendships_create($params=array()) {
		$url = $this->base_api_url . 'friendships/create.json';
		return $this->__query($url,$params,'post');
	}
	function friendships_destroy($params=array()) {
		$url = $this->base_api_url . 'friendships/destroy.json';
		return $this->__query($url,$params,'post');
	}
	function friendships_show($params=array()) {
		$url = $this->base_api_url . 'friendships/show.json';
		return $this->__query($url,$params,'get');
	}
    /* Social Graph */
	function friends_ids($params=array()) {
		$url = $this->base_api_url . 'friends.json';
		return $this->__query($url,$params,'get');
	}
	function followers_ids($params=array()) {
		$url = $this->base_api_url . 'followers.json';
		return $this->__query($url,$params,'get');
	}
			/* Account */
	function account_verify_credentials($params=array()) {
		$url = $this->base_api_url . 'account/verify_credentials.json';
		return $this->__query($url,$params,'get');
	}
	function account_rate_limit_status($params=array()) {
		$url = $this->base_api_url . 'account/rate_limit_status.json';
		return $this->__query($url,$params,'get');
	}
	function account_update_delivery_device($params=array()) {
		$url = $this->base_api_url . 'account/update_delivery_device.json';
		return $this->__query($url,$params,'post');
	}
	function account_update_profile_colors($params=array()) {
		$url = $this->base_api_url . 'account/update_profile_colors.json';
		return $this->__query($url,$params,'post');
	}
	function account_update_profile_image($params=array()) {
		$url = $this->base_api_url . 'account/update_profile_image.json';
		return $this->__query($url,$params,'post');
	}
	function account_update_profile_background_image($params=array()) {
		$url = $this->base_api_url . 'account/update_profile_background_image.json';
		return $this->__query($url,$params,'post');
	}
	function account_update_profile($params=array()) {
		$url = $this->base_api_url . 'account/update_profile.json';
		return $this->__query($url,$params,'post');
	}
			/* Favorite */
	function favorites($params=array()) {
		$url = $this->base_api_url . 'favorites.json';
		return $this->__query($url,$params,'get');
	}
	function favorites_create($params=array()) {
		$url = $this->base_api_url . 'favorites/create.json';
		return $this->__query($url,$params,'post');
	}
	function favorites_destroy($params=array()) {
		$url = $this->base_api_url . 'favorites/destroy.json';
		return $this->__query($url,$params,'post');
	}
    /* Notification */
	function notifications_follow($params=array()) {
		$url = $this->base_api_url . 'notifications/follow.json';
		return $this->__query($url,$params,'post');
	}
	function notifications_leave($params=array()) {
		$url = $this->base_api_url . 'notifications/leave.json';
		return $this->__query($url,$params,'post');
	}
    /* Block */
	function blocks_create($params=array()) {
		$url = $this->base_api_url . 'blocks/create.json';
		return $this->__query($url,$params,'post');
	}
	function blocks_destroy($params=array()) {
		$url = $this->base_api_url . 'blocks/destroy.json';
		return $this->__query($url,$params,'post');
	}
	function blocks_exists($params=array()) {
		$url = $this->base_api_url . 'blocks/exists.json';
		return $this->__query($url,$params,'get');
	}
	function blocks_blocking($params=array()) {
		$url = $this->base_api_url . 'blocks/blocking.json';
		return $this->__query($url,$params,'get');
	}
	function blocks_blocking_ids($params=array()) {
		$url = $this->base_api_url . 'blocks/blocking/ids.json';
		return $this->__query($url,$params,'get');
	}
    /* Spam Reporting */
	function report_spam($params=array()) {
		$url = $this->base_api_url . 'report_spam.json';
		return $this->__query($url,$params,'post');
	}
	/* Internal methods */
	private function __query($url, $params, $httpMethod='get') {
        CakeLog::write('request', $url);
		if (strtolower($httpMethod) == 'post') {
			$response = $this->__postRequest($url,$params);
		}
		else {
			$response = $this->__getRequest($url, $params);
		}

		return Set::reverse(json_decode($response));
	}
	
	private function __getRequest($url, $params) {
        if (!empty($params['auth']['username']) &&
            !empty($params['auth']['password'])) {
            extract($params['auth']);
            unset($params['auth']);
            $qs = http_build_query($params);
            $url = (!empty($qs)) ? $url . '?' . $qs : $url;

            $request = array(
                    'method' => 'GET',
                    'uri' => $url,
                    'auth' => array(
                        'method' => 'Basic',
                        'user' => $username,
                        'pass' => $password,
                        ),
                    'version' => '1.1',
                    'body' => '',
                    'line' => null,
                    'header' => array(
                        'Connection' => 'close',
                        'User-Agent' => 'CakePHP'
                        ),
                    'raw' => null,
                    'cookies' => array()
                    );

            $return = $this->httpSocket->request($request);
            return $return;
        } 

        return $this->httpSocket->get($url);
    }

    private function __postRequest($url, $params) {
        $data = array_diff_key($params, array('auth' => null));
        if (!empty($params['auth']['username']) &&
            !empty($params['auth']['password'])) {
            extract($params['auth']);
            $request = array(
                    'method' => 'POST',
                    'uri' => $url,
                    'auth' => array(
                        'method' => 'Basic',
                        'user' => $username,
                        'pass' => $password,
                        ),
                    'version' => '1.1',
                    'body' => $data,
                    'line' => null,
                    'header' => array(
                        'Connection' => 'close',
                        'User-Agent' => 'CakePHP'
                        ),
                    'raw' => null,
                    'cookies' => array()
                    );

            $return = $this->httpSocket->request($request);
            return $return;
        } 
        return $this->httpSocket->post($url,$data);
    }
}
?>
